package Functions;

import java.util.ArrayList;



public class Polynomial extends Functions 
{

	private double[][] poly = new double[2][1];
	private int maxExp;
	private double[] myPolynomial;

	//constructors 
 	public Polynomial(double coef, int exp) 
	{
		type = 0;
		function = null;
		poly[0][0] = coef;
		poly[1][0] = exp;
		sortArray();
	}
	
	public Polynomial(double[][]newA) 
	{
		type = 0;
		function = null;
		poly=newA;
		sortArray();
	}
		
	public Polynomial() 
	{
		type = 0;
		function = null;
		sortArray();
	}

	
	//setters and getters
	public int getNoOfTerms()
	{
		return poly[0].length;
	}
	
	public double[][] getPoly() 
	{
		return poly;
	}

	public void setPoly(double[][] poly) 
	{
		this.poly = poly;
	}
	
	public double getCoef(int i)
	{
		return poly[0][i];
	}
	
	public double getExponent(int i)
	{
		return poly[1][i];
	}
	
	public int getMax()
	{
		return maxExp;
	}
 
	public void setMax(int max)
	{
		maxExp = max;
	}
	
	public double[] getMyPoly()
	{
		return myPolynomial;
	}
	
	public void setMyPoly(double[] newPoly)
	{
		myPolynomial = newPoly;
	}

	
	//Methods 
	private void getMaxExp()
	{
	    maxExp = (int)getExponent(0);
		for(int i=1 ; i<getNoOfTerms();i++)
		{
			int current = (int) getExponent(i);
			if(current> maxExp) 
			{
				maxExp = (int)current;
			}
		}
	}

	private void  sortArray()
	{
		getMaxExp();
		double[] newPoly = new double[maxExp+1];
		for(int i=0;i<getNoOfTerms();i++)
		{
		   	int exp = (int) getExponent(i);
		   	newPoly[exp] += getCoef(i);
		}
		myPolynomial = newPoly;
	}
	
	//Operations
	public Polynomial addition(Polynomial p)
	{
		int max = Math.max(maxExp, p.getMax())+1;
		double[] newCoef = new double [max]; 
		for(int i=0;i<myPolynomial.length;i++)
		{
			newCoef[i] = myPolynomial[i];
		}
		for(int i=0;i<p.getMax()+1;i++)
		{
			newCoef[i] += p.getMyPoly()[i];
		}
		Polynomial newPoly = new Polynomial();
		newPoly.setMax(max-1);
		newPoly.setMyPoly(newCoef);
		return newPoly;
	}
	
	public Polynomial subtraction(Polynomial p)
	{
		int max = Math.max(maxExp, p.getMax())+1;
		double[] newCoef = new double [max]; 
		for(int i=0;i<myPolynomial.length;i++)
		{
			newCoef[i] = myPolynomial[i];
		}
		for(int i=0;i<p.getMax()+1;i++)
		{
			newCoef[i] -= p.getMyPoly()[i];
		}
		Polynomial newPoly = new Polynomial();
		newPoly.setMax(max-1);
		newPoly.setMyPoly(newCoef);
		return newPoly;
	}
	
	public Polynomial multiplication(Polynomial p)
	{
		int max = maxExp + p.getMax()+1;
		double[] newCoef = new double [max]; 
		for(int i=0;i<myPolynomial.length;i++)
		{
			for(int j=0;j<p.getMax()+1;j++)
			{
				newCoef[i+j] += myPolynomial[i] * p.getMyPoly()[j];
			}
		}
		Polynomial newPoly = new Polynomial();
		newPoly.setMax(max-1);
		newPoly.setMyPoly(newCoef);
		return newPoly;
	}


	public Element differentiate()
	{
		double[] newCoef=null;
		if(maxExp!=0)
		{
		    newCoef = new double[maxExp];
			for(int i=1;i<myPolynomial.length;i++)
			{
				newCoef[i-1]= i*myPolynomial[i];
			}
		}
		else
		{
			return null;
		}
		Polynomial newPoly = new Polynomial();
		newPoly.setMax(maxExp-1);
		newPoly.setMyPoly(newCoef);
		ArrayList<Functions> ele = new ArrayList<Functions>();
		ele.add(newPoly);
		Element e = new Element(ele);
		return e;
	}
	
	public double evaluate(double x)
	{
		double value=0;
		for(int i=0;i<myPolynomial.length;i++)
		{
			value += Math.pow(x, i)*myPolynomial[i];
		}
		return value;
	}

	public static void main(String[] args) {
		double[][] d = {{1},{0}};
		double[][] d1 = {{5,7},{2,0}};
		Polynomial p = new Polynomial(d);
		Polynomial p1 = new Polynomial(d1);
		p=p.multiplication(p1);
		for(int i=0;i<p.myPolynomial.length;i++)
		{
			System.out.println(p.myPolynomial[i]);
		}
		double s = p1.evaluate(2.5);
		System.out.println(s);
		double o = (5*Math.pow(2.5, 2))+7;
		System.out.println(o);
	}

	
}
